Option Explicit

' ======================================================================
' Descriptor
' 列元素容器
' ======================================================================

' ======================================================================
' Implement
' ======================================================================

Implements ISqlFormatterElem

' ======================================================================
' Field
' ======================================================================

' ==================================================
' Field
' ==================================================
' 用来所有组成元素: 子列对象 + 运算符
' IObjArrayRef<ISqlFormatterElem>
Private componentArray As IObjArrayRef

' ==================================================
' ISqlFormatterElem Field
' ==================================================
' 前缀空格的数量
' 默认值 = 0
Private prefixSpaceCount As Integer

' 左侧括号的数量
' 默认值 = 0
Private leftParenthesisCount As Integer
' 右侧括号的数量
' 默认值 = 0
Private rightParenthesisCount As Integer

' 当前对象是否是多行的状态
' 默认值 = False
Private multiLineState As Boolean
' 元素数组是否是以注释结尾
' 默认值 = False
Private componentArrayIsEndsWithComment As Boolean

' ======================================================================
' Constructor
' ======================================================================
Private Sub Class_Initialize()
    ' 组成条件的所有元素
    Set componentArray = UtilsArrayRef.createRealObjArrayRef(8)
End Sub

Private Sub Class_Terminate()
    Set componentArray = Nothing
End Sub

' ======================================================================
' implements ISqlFormatterElem Function
' ======================================================================
' ==================================================
' ISqlFormatterElem -- 添加组成元素
' ==================================================
' 添加组成元素
Public Sub ISqlFormatterElem_addComponent(ByRef c As ISqlFormatterElem)

    ' ==================================================
    ' 1. 参数检查
    ' ==================================================
    ' 1. 检查: 如果元素是 `null` 则退出
    If c Is Nothing Then
        Exit Sub
    End If

    ' ==================================================
    ' 2. 保存元素
    ' ==================================================
    ' 1. 将元素保存到元素数组中
    componentArray.Add c

    With c ' -------> 在这里加速
        ' ==================================================
        ' 3. 设置当前对象的组成元素是不是多行的状态
        ' ==================================================
        ' 1. 检查: 如果当前对象不是多行的状态 `multiLineState == false`，则继续
        If multiLineState = False Then
            ' 2. 检查: 如果当前元素是多行的，则设置 `multiLineState = true`
            If .isMultiLine Then
                multiLineState = True

            ' 3. 否则，检查: 如果元素数组是以注释结尾的 `componentArrayIsEndsWithComment == true`，则设置 `multiLineState = true`
            ElseIf componentArrayIsEndsWithComment Then
                multiLineState = True

            ' 4. 否则，检查: 如果当前元素是单独一行的注释
            ElseIf .isSingleLineComment Then
                ' 4.1. 如果元素数组中的元素数量 > 1 ，则设置 `multiLineState = true`
                If componentArray.Count > 1 Then
                    multiLineState = True
                End If
            End If
        End If

        ' ==================================================
        ' 4. 保存元素数组是否是以注释结尾的
        ' ==================================================
        ' 1. 将当前元素的是否以注释结尾的结果: `isEndsWithComment() == true` 保存到属性 `componentArrayIsEndsWithComment`
        componentArrayIsEndsWithComment = .isEndsWithComment
    End With
End Sub

' 将元素添加到开头位置
Public Sub ISqlFormatterElem_addComponentToFirst(ByRef c As ISqlFormatterElem)

    ' ==================================================
    ' 1. 参数检查
    ' ==================================================
    ' 1. 检查: 如果元素是 `null` 则退出
    If c Is Nothing Then
        Exit Sub
    End If

    With c ' -------> 在这里加速
        ' ==================================================
        ' 2. 保存元素
        ' ==================================================
        ' 1. 将元素添加到开头位置
        componentArray.AddFirst c

        ' 2. 获取元素数量 和 当前元素是否是以注释结尾
        Dim componentArrayCount As Long
        componentArrayCount = componentArray.Count

        Dim curIsEndsWithComment As Boolean
        curIsEndsWithComment = .isEndsWithComment

        ' ==================================================
        ' 3. 设置当前对象的组成元素是不是多行的状态
        ' ==================================================
        ' 1. 检查: 如果当前对象不是多行的状态 `multiLineState == false`，则继续
        If multiLineState = False Then
            ' 2. 检查: 如果当前元素是多行的，则设置 `multiLineState = true`
            If .isMultiLine Then
                multiLineState = True

            ' 3. 否则，检查: 如果元素数量 > 1
            ElseIf componentArrayCount > 1 Then
                ' 3.1. 检查: 如果当前元素是注释结尾，则是多行
                '    (说明在单行的基础行，又增加了一个包含注释的内容，所以变成了多行)
                If curIsEndsWithComment Then
                    multiLineState = True

                ' 3.2. 否则，检查: 如果第二个元素是单行注释，则设置为多行的
                Else
                    Dim tempElem As ISqlFormatterElem
                    Set tempElem = componentArray.Item(1)
                    If tempElem.isSingleLineComment Then
                        multiLineState = True
                    End If
                End If
            End If
            ' 4. 否则 (到这里说明只有一个元素，则不用检查，无论是哪种情况都是单行的)
        End If

        ' ==================================================
        ' 4. 如果当前只有一个元素，则保存: 是否是以注释结尾
        ' ==================================================
        If componentArrayCount = 1 Then
            componentArrayIsEndsWithComment = curIsEndsWithComment
        End If
    End With
End Sub

' 能否将元素添加到开头位置
Public Function ISqlFormatterElem_canAddComponentToFirst() As Boolean
    ' 不存在左边界括号时，可以将元素添加到开头
    ISqlFormatterElem_canAddComponentToFirst = (leftParenthesisCount <= 0)
End Function

' ==================================================
' ISqlFormatterElem -- 对齐处理
' ==================================================
' 该方法是用来配置对齐的方法
' 返回元素内，最多一级深度下的对齐元素组
' 如果是列对象，则返回作用域各个组成元素内的条件组（主要是子查询）
' 如果是条件对象，则返回条件自身
' 如果是作用域对象，则返回作用域内各部分中的条件组合
' 如果是赋值语句，则返回语句自身
' 如果没有条件或者赋值语句，则返回 null
'
' @return IObjArrayRef<IObjArrayRef<ISqlFormatterAlignmentElem>>
Public Function ISqlFormatterElem_getAlignmentElemGroups() As IObjArrayRef
    ' Dim result As IObjArrayRef
    Dim groups As IObjArrayRef

    Dim temp As ISqlFormatterElem

    Dim i As Long
    For i = 0 To componentArray.MaxIndex
        Set temp = componentArray.Item(i)

        Set groups = temp.getAlignmentElemGroups
        If Not groups Is Nothing Then
            If ISqlFormatterElem_getAlignmentElemGroups Is Nothing Then
                Set ISqlFormatterElem_getAlignmentElemGroups = UtilsArrayRef.createRealObjArrayRef
            End If

            ISqlFormatterElem_getAlignmentElemGroups.mergeArrRef groups
        End If
    Next

    ' return result --> ISqlFormatterElem_getAlignmentElemGroups
End Function

' ==================================================
' ISqlFormatterElem -- 前缀空格设置
' ==================================================
' 设置当前元素的嵌套深度，并计算前缀空格的数量
' 会覆盖 setPrefixSpaceCount 的设置结果
Public Sub ISqlFormatterElem_setElemNestCount(ByVal nestCount As Integer, ByRef config As SqlFormatterConfiguration)
    prefixSpaceCount = nestCount * config.elemNestLevelPrefixSpaceCount

    ' 如果存在边界括号，则每一个子列都需要额外附加一级深度
    Dim subColNestCount As Integer
    subColNestCount = nestCount
    If ISqlFormatterElem_hasBoundaryParenthesis Then
        subColNestCount = subColNestCount + 1
    End if

    ' 处理第一个元素
    Dim temp As ISqlFormatterElem
    Dim i As Long

    ' 如果没有多行元素
    If multiLineState = false Then
        For i = 0 To componentArray.MaxIndex
            Set temp = componentArray.Item(i)
            temp.setElemNestCount subColNestCount, config
        Next

    Else
        ' 需要记录是否发现过一个非注释的元素
        ' 如果发现了非注释的多行，或者单行以注释结尾的元素就需要停止遍历

        ' 标记: 是否发现了元素
        Dim hasElem As Boolean
        ' hasElem = false

        For i = 0 To componentArray.MaxIndex
            Set temp = componentArray.Item(i)

            ' 如果发现了多行元素
            If temp.isMultiLine Then
                ' 如果之前发现了元素，则退出遍历，并且 i--，
                If hasElem Then
                    i = i - 1
                    Goto loopBreak

                ' 否则，设置当前元素的深度，并退出遍历
                Else
                    temp.setElemNestCount subColNestCount, config
                    Goto loopBreak
                End If

            ' 否则，如果是单行元素(不是多行，也不是注释)
            ElseIf temp.isComment = False Then
                ' 设置深度
                temp.setElemNestCount subColNestCount, config
                ' 如果元素以注释结尾，并退出遍历
                If temp.isEndsWithComment Then
                    Goto loopBreak
                End If

                ' 否则(只是普通单行元素)，则进行标记
                hasElem = true

            ' 否则，是注释
            Else
                ' 如果已经发现了其他非注释元素(单行的)，则退出遍历
                If hasElem Then
                    Goto loopBreak
                End If
            End If
        Next
loopBreak:

        ' 处理剩余的元素，每个元素额外添加一级深度
        ' (这里是发生换行后的剩余元素，所以都需要额外增加一级深度)
        subColNestCount = subColNestCount + 1
        For i = i + 1 To componentArray.MaxIndex
            Set temp = componentArray.Item(i)
            temp.setElemNestCount subColNestCount, config
        Next
    End If
End Sub

' 直接设置前缀空格的数量
' 将会覆盖 setElemNestCount 对前缀空格数量的控制
Public Sub ISqlFormatterElem_setPrefixSpaceCount(ByVal spaceCount As Integer, ByRef config As SqlFormatterConfiguration)
    prefixSpaceCount = spaceCount

    ' 如果存在边界括号，则每一个子列都需要额外附加一级深度
    Dim subColPrefixSpaceCount As Integer
    subColPrefixSpaceCount = spaceCount
    If ISqlFormatterElem_hasBoundaryParenthesis Then
        subColPrefixSpaceCount = config.elemNestLevelPrefixSpaceCount
    End If

    ' 处理第一个元素
    Dim temp As ISqlFormatterElem
    Dim i As Long

    ' 如果没有多行元素
    If multiLineState = False Then
        For i = 0 To componentArray.MaxIndex
            Set temp = componentArray.Item(i)
            temp.setPrefixSpaceCount subColPrefixSpaceCount, config
        Next
    
    Else
        ' 需要记录是否发现过一个非注释的元素
        ' 如果发现了非注释的多行，或者单行以注释结尾的元素就需要停止遍历

        ' 标记: 是否发现了元素
        Dim hasElem As Boolean
        hasElem = false
        For i = 0 To componentArray.MaxIndex
            Set temp = componentArray.Item(i)

            ' 如果发现了多行元素
            If temp.isMultiLine Then
                ' 如果之前发现了元素，则退出遍历，并且 i--
                If hasElem Then
                    i = i - 1
                    Goto loopBreak

                ' 否则，设置当前元素的深度，并退出遍历
                Else
                    temp.setPrefixSpaceCount subColPrefixSpaceCount, config
                    Goto loopBreak
                End If

            ' 否则，如果是单行元素(不是多行，也不是注释)
            ElseIf temp.isComment = False Then
                ' 设置深度
                temp.setPrefixSpaceCount subColPrefixSpaceCount, config
                ' 如果元素以注释结尾，并退出遍历
                If temp.isEndsWithComment Then
                    Goto loopBreak
                End If
                ' 否则(只是普通单行元素)，则进行标记
                hasElem = True

            ' 否则，是注释
            Else
                ' 如果已经发现了其他非注释元素(单行的)，则退出遍历
                If hasElem Then
                    Goto loopBreak
                End If
            End If
        Next
loopBreak:

        ' 处理剩余的元素，每个元素额外添加一级深度
        ' (这里是发生换行后的剩余元素，所以都需要额外增加一级深度)
        subColPrefixSpaceCount = subColPrefixSpaceCount + config.elemNestLevelPrefixSpaceCount
        For i = i + 1 To componentArray.MaxIndex
            Set temp = componentArray.Item(i)
            temp.setPrefixSpaceCount subColPrefixSpaceCount, config
        Next
    End If
End Sub

' ==================================================
' ISqlFormatterElem -- 边界括号
' ==================================================
' 是否存在边界括号，有左边或者右边都返回 true
Public Function ISqlFormatterElem_hasBoundaryParenthesis() As Boolean
    If leftParenthesisCount > 0 Then
        ISqlFormatterElem_hasBoundaryParenthesis = True
    ElseIf rightParenthesisCount > 0 Then
        ISqlFormatterElem_hasBoundaryParenthesis = True
    End If

    ' return False
End Function

' 边界处的 [(] 的数量 + count 个
Public Sub ISqlFormatterElem_addBoundaryLeftParenthesis(Optional ByVal count As Integer = 1)
    leftParenthesisCount = leftParenthesisCount + count
End Sub

' 边界处的 [)] 的数量 + count 个
Public Sub ISqlFormatterElem_addBoundaryRightParenthesis(Optional ByVal count As Integer = 1)
    rightParenthesisCount = rightParenthesisCount + count
End Sub

' ==================================================
' ISqlFormatterElem -- 内容检查
' ==================================================
' 获取类型
Public Function ISqlFormatterElem_getType() As SqlTokenType
    ' 没有对应的类型，暂时使用函数
    ISqlFormatterElem_getType = SqlTokenType.STR_FUNC
End Function

' 检查当前元素是不是一个注释
Public Function ISqlFormatterElem_isComment() As Boolean
    ' return false
End Function

' 检查当前元素是不是和前一个元素处于同一行的注释
Public Function ISqlFormatterElem_isShareLineComment() As Boolean
    ' return false
End Function

' 检查当前元素是不是处于单独一行的注释
Public Function ISqlFormatterElem_isSingleLineComment() As Boolean
    ' return false
End Function

' 检查当前元素是不是以注释结尾
Public Function ISqlFormatterElem_isEndsWithComment() As Boolean
    ' 1. 如果存在右括号，则默认不是以注释结尾
    If rightParenthesisCount > 0 Then
        ' return false
        Exit Function
    End If

    ' 2. 返回元素数组是否以注释结尾
    ISqlFormatterElem_isEndsWithComment = componentArrayIsEndsWithComment
End Function

' 检查当前生成器是不是多行的
Public Function ISqlFormatterElem_isMultiLine() As Boolean
    ' 检查: 如果已经是多行的，则返回 true
    If multiLineState Then
        ISqlFormatterElem_isMultiLine = True
        Exit Function
    End IF

    ' 检查: 如果最后一个组成元素以注释结尾，则继续
    If componentArrayIsEndsWithComment Then
        ' 如果最后一个组成元素是以注释结尾，则如果还存在边界括号，就是多行的
        ISqlFormatterElem_isMultiLine = ISqlFormatterElem_hasBoundaryParenthesis
    End If

    ' 否则: 返回 false
    ' return false
End Function

' ==================================================
' ISqlFormatterElem -- 生成列的字符串
' ==================================================
' 生成一整行的字符串。如果本身是多行，将会使用换行符进行连接
Public Function ISqlFormatterElem_toString(ByRef config As SqlFormatterConfiguration) As String
    If ISqlFormatterElem_isMultiLine = False Then
        ' 1. 如果是单行的，则直接生成单行字符串
        ISqlFormatterElem_toString = doCreateSingleLineString(config)
        Exit Function
    Else
        ' 1. 生成原始字符集合
        Dim arrRef As IPrimitiveArrayRef
        Set arrRef = doCreateMultiLineArray(config)
        ' 2. 使用换行符连接
        ISqlFormatterElem_toString = UtilsArrayRef.reducePrimitiveArrayRefToStr(arrRef, config.lineBreak)
        Exit Function
    End If
End Function

' 生成多行字符串
' 如果只有一行，则返回的数组引用中将会只有一个
' 并且不会在开头附加前缀空格
'
' @return IPrimitiveArrayRef<String>
Public Function ISqlFormatterElem_toStringArray(ByRef config As SqlFormatterConfiguration) As IPrimitiveArrayRef
    ' ==================================================
    ' 1. 处理单行的情况
    ' ==================================================
    ' 1. 检查: 如果是单行的，则生成单行字符串
    If ISqlFormatterElem_isMultiLine = False Then
        Dim singleStr As String
        singleStr = doCreateSingleLineString(config)

        ' 2. 将 `singleStr` 包装成一个长度为 1 的结果集合，并返回
        Set ISqlFormatterElem_toStringArray = UtilsArrayRef.wrapperToPrimitiveArrayRef(singleStr)
        Exit Function
    End If

    ' ==================================================
    ' 2. 处理多行的情况
    ' ==================================================
    ' 1. 生成多行字符串集合，返回生成结果
    Set ISqlFormatterElem_toStringArray = doCreateMultiLineArray(config)
End Function

' ======================================================================
' Private Function
' ======================================================================
' 生成单行字符串
Private Function doCreateSingleLineString(ByRef config As SqlFormatterConfiguration) As String
    doCreateSingleLineString = SqlFormatterHelper.createFormatSingleStr( _
        componentArray, config, leftParenthesisCount, rightParenthesisCount)
End Function

' 生成表达式列的字符串集合
' @return IPrimitiveArrayRef<String>
Private Function doCreateMultiLineArray(ByRef config As SqlFormatterConfiguration) As IPrimitiveArrayRef
    ' ==================================================
    ' 1. 声明变量
    ' ==================================================
    ' 1. 结果集合 `IPrimitiveArrayRef<String> result = UtilsArrayRef.createRealPrimitiveArrayRef<String>(8)`
    Dim result As IPrimitiveArrayRef
    Set result = UtilsArrayRef.createRealPrimitiveArrayRef(8)

    ' 2. 前缀字符串 `String prefixSpaceStr = ""`
    Dim prefixSpaceStr As String
    ' 3. 临时元素 `ISqlFormatterElem component`
    Dim component As ISqlFormatterElem
    ' 4. 元素字符串集合 `IPrimitiveArrayRef<String> strArr`
    Dim strArr As IPrimitiveArrayRef
    ' 5. 遍历索引 `long i = 0`
    Dim i As Long
    i = 0
    ' 6. 行字符串 `String lineStr = ""`
    Dim lineStr As String

    ' ==================================================
    ' 2. 处理前缀空格
    ' ==================================================
    ' 1. 检查: 如果当前列对象存在边界括号，则继续
    If ISqlFormatterElem_hasBoundaryParenthesis = True Then
        ' 2. 生成一个单位的前缀空格 `prefixSpaceStr += config.elemNestLevelPrefixSpace`
        prefixSpaceStr = config.elemNestLevelPrefixSpace
    End If

    ' ==================================================
    ' 3. 处理左边界括号
    ' ==================================================
    ' 1. 如果存在左边界括号，则继续: `leftParenthesisCount > 0`
    If leftParenthesisCount > 0 Then
        ' 2. 生成等量的左括号，并保存到 `lineStr`: `UtilsString.repeatLeftParenthesis()`
        lineStr = UtilsString.repeatLeftParenthesis(leftParenthesisCount)
        ' 3. 尝试吸收后面出现的同行注释
        ' 3.1. 检查: 如果组成元素数量 > 0，则继续:
        If componentArray.Count > 0 Then
            ' 3.2. 获取第一个元素，保存到 `component`
            Set component = componentArray.Item(0)
            ' 3.3. 检查: 如果元素类型是同行注释，则继续: `component.isShareLineComment() == true`
            If component.isShareLineComment Then
                ' 3.4. 连接字符串 `lineStr += " " + component.toString(config)`
                lineStr = lineStr & " " & component.toString(config)
                ' 3.5. 设置 `i = 1`
                i = 1
            End If
        End If

        ' 4. 将 `lineStr` 保存到 `result`
        result.Add lineStr
        ' 5. 设置 `lineStr` 为空字符串
        lineStr = ""
    End If

    ' ==================================================
    ' 4. 处理换行前的内容
    ' ==================================================
    ' 1. 从 `i = i` 开始到 `componentArray.MaxIndex`, 遍历 `componentArray`
    For i = i To componentArray.MaxIndex
        ' 2. 获取第 i 个元素，保存到 `component`
        Set component = componentArray.Item(i)
        ' 3. 检查: 如果元素是注释: `component.isComment() == true`
        If component.isComment Then
            ' 3.1. 检查: 如果行字符串是空 `lineStr == ""`，则将这行注释保存到 `result`
            If lineStr = "" Then
                ' 说明这是处在开头的注释，还没有遇到一个有效的元素，需要继续遍历
                result.Add component.toString(config)

            ' 3.2. 否则，检查: 如果是单独一行的注释 `component.isSingleLineComment() == true`
            ElseIf component.isSingleLineComment Then
                ' 3.2.1. 将 `prefixSpaceStr + lineStr` 保存到 `result`
                result.Add prefixSpaceStr & lineStr
                ' 3.2.2. 将 `prefixSpaceStr + 这一行注释` 保存到 `result`
                result.Add prefixSpaceStr & component.toString(config)
                ' 3.2.3. 设置 `lineStr` 为空字符串
                lineStr = ""
                ' 3.2.4. 退出遍历
                Goto loopBreak

            ' 3.3. 否则 (是和前一个元素同一行的注释)
            Else
                ' 3.3.1. 将 `prefixSpaceStr + lineStr + " " + 注释内容` 保存到 `result`
                result.Add prefixSpaceStr & lineStr & " " & component.toString(config)
                ' 3.3.2. 设置 `lineStr` 为空字符串
                lineStr = ""
                ' 3.3.3. 退出遍历
                Goto loopBreak
            End If

        ' 4. 否则，检查: 如果元素是单行的: `component.isMultiLine() == false`
        ElseIf component.isMultiLine = False Then
            ' 4.1. 连接 `lineStr` 和 `component.toString(config)`，结果保存到 `lineStr`
            lineStr = SqlFormatterHelper.joinTwoElemStr(lineStr, component.toString(config))

            ' 4.2. 检查: 如果元素是以注释结尾的: `component.isEndsWithComment() == true`
            If component.isEndsWithComment Then
                ' 4.2.1. 将 `prefixSpaceStr + lineStr` 保存到 `result`
                result.Add prefixSpaceStr & lineStr
                ' 4.2.2. 设置 `lineStr` 为空字符串
                lineStr = ""
                ' 4.2.3. 退出遍历
                Goto loopBreak
            End If

        ' 5. 否则 (是多行的)
        Else
            ' 5.1. 检查: 如果 `lineStr` 不是空字符串 (说明在多行元素之前就已经有元素了，所以需要在后面处理多行元素)
            If lineStr <> "" Then
                ' 5.1.1. 将 `prefixSpaceStr + lineStr` 保存到 `result`
                result.Add prefixSpaceStr & lineStr
                ' 5.1.2. 设置 `i = i - 1`，以保证后面能从这个多行元素开始
                i = i - 1
                ' 5.1.3. 设置 `lineStr` 为空字符串
                lineStr = ""

            ' 5.2. 否则，处理多行字符串 (说明这里是第一次遇到多行元素)
            Else
                ' 5.2.1. 生成元素的多行字符串集合，保存到 `strArr`
                Set strArr = component.toStringArray(config)
                ' 5.2.2. 将 `strArr` 保存到 `result`
                UtilsArrayRef.mergeArrayRefWithPrefix result, strArr, prefixSpaceStr
            End If
            ' 5.3. 退出遍历
            Goto loopBreak
        End If
    Next
loopBreak:

    ' ==================================================
    ' 5. 快速结束
    ' ==================================================
    ' 1. 检查: 如果 `lineStr` 不是空字符串，将 `prefixSpaceStr + lineStr` 保存到 `result`
    '    这里处理以下这种情况
    '    ```sql
    '    -- xxxx
    '    abc
    '    ```
    If lineStr <> "" Then
        result.Add prefixSpaceStr & lineStr
        ' 2. 退出处理，并返回 `result`
        Set doCreateMultiLineArray = result
        Exit Function
    End If

    ' ==================================================
    ' 6. 处理剩余元素之前的初始化
    ' ==================================================
    ' 1. 额外增加一个单位的前缀空格 `prefixSpaceStr += config.elemNestLevelPrefixSpace`
    prefixSpaceStr = prefixSpaceStr + config.elemNestLevelPrefixSpace

    ' ==================================================
    ' 7. 处理剩余的元素
    ' ==================================================
    ' 1. 从 `i = nextIndex` 开始到 `componentArray.MaxIndex`, 遍历 `componentArray`
    For i = i + 1 To componentArray.MaxIndex
        ' 2. 获取第 i 个元素，保存到 `component`
        Set component = componentArray.Item(i)

        ' 3. 检查: 如果元素是多行的: `component.isMultiLine() == true`
        If component.isMultiLine Then
            ' 3.1. 检查: 如果 `lineStr` 不是空字符串
            If lineStr <> "" Then
                ' 3.1.1. 将 `prefixSpaceStr + lineStr` 保存到 `result`
                result.Add prefixSpaceStr & lineStr
                ' 3.1.2. 重制 `lineStr` 为空字符串
                lineStr = ""
            End If

            ' 3.2. 生成 `component` 的多行字符串集合，保存到 `strArr`
            Set strArr = component.toStringArray(config)

            ' 3.3. 将 `strArr` 保存到 `result`
            UtilsArrayRef.mergeArrayRefWithPrefix result, strArr, prefixSpaceStr

        ' 4. 否则，检查: 如果当前元素是注释
        ElseIf component.isComment Then
            ' 4.1 检查: 如果当前元素是和前一个元素处于同一行的注释
            If component.isShareLineComment Then
                ' 4.1.1 将 `prefixSpaceStr + lineStr + " " + component.toString(config)` 保存到 `result`
                result.Add prefixSpaceStr & lineStr & " " & component.toString(config)
                ' 4.1.2. 重制 `lineStr` 为空字符串
                lineStr = ""

            ' 4.2. 否则 (当前元素是处于单独一行的注释)
            Else
                ' 4.2.1. 检查: 如果 `lineStr` 不是空字符串
                If lineStr <> "" Then
                    ' 4.2.1.1. 将 `prefixSpaceStr + lineStr` 保存到 `result`
                    result.Add prefixSpaceStr & lineStr
                    ' 4.2.1.2. 重制 `lineStr` 为空字符串
                    lineStr = ""
                End If
                ' 4.2.2. 将 `prefixSpaceStr + component.toString(config)` 保存到 `result`
                result.Add prefixSpaceStr & component.toString(config)
            End If

        ' 5. 否则 (元素是单行的)
        Else
            ' 5.1. 连接 `lineStr + component.toString(config)`，结果保存到 `lineStr`
            lineStr = SqlFormatterHelper.joinTwoElemStr(lineStr, component.toString(config))
            ' 5.2. 检查: 如果元素是以注释结尾的
            If component.isEndsWithComment Then
                ' 5.2.1. 将 `prefixSpaceStr + lineStr` 保存到 `result`
                result.Add prefixSpaceStr & lineStr
                ' 5.2.2. 重制 `lineStr` 为空字符串
                lineStr = ""
            End If
        End If
    Next

    ' ==================================================
    ' 8. 处理最后一行
    ' ==================================================
    ' 1. 检查: 如果 `lineStr` 不是空字符串，则将 `prefixSpaceStr + lineStr` 保存到 `result`
    If lineStr <> "" Then
        result.Add prefixSpaceStr & lineStr
    End If

    ' ==================================================
    ' 9. 处理右边界括号
    ' ==================================================
    ' 1. 如果存在右边界括号，则继续: `rightParenthesisCount > 0`
    If rightParenthesisCount > 0 Then
        ' 2. 生成等量的右括号，并保存到 `result`
        result.Add UtilsString.repeatRightParenthesis(rightParenthesisCount)
    End If

    ' ==================================================
    ' 10. 退出处理，返回 `result`
    ' ==================================================
    Set doCreateMultiLineArray = result
End Function